package com.study.talk.ui.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.TextPaint;
import android.text.TextWatcher;
import android.util.AttributeSet;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatEditText;

import com.study.talk.R;

public class CodeView extends AppCompatEditText {

    private Integer maxLength = 4;
    private Integer squareSize = 80;
    private Integer squareSpacing = 80;
    private Drawable drawable;

    private Integer textColor;

    private InputCompleteListener inputCompleteListener;

    private Rect rect = new Rect();

    public CodeView(@NonNull Context context) {
        super(context);
    }

    public CodeView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public CodeView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(@NonNull Context context, AttributeSet attrs) {
        initAttrs(context, attrs);
    }

    private void initAttrs(@NonNull Context context, @Nullable AttributeSet attrs) {
        if (null == attrs) {
            throw new IllegalArgumentException("attrs is null");
        } else {
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CodeView);

            maxLength = typedArray.getInt(R.styleable.CodeView_android_maxLength, 4);

            if (maxLength < 4) throw new IllegalArgumentException("maxLength can't be less than 4");

            squareSize = (int) typedArray.getDimension(R.styleable.CodeView_squareSize, squareSize);

            squareSpacing = (int) typedArray.getDimension(R.styleable.CodeView_squareSpacing, squareSpacing);

            drawable = typedArray.getDrawable(R.styleable.CodeView_squareDrawable);

            typedArray.recycle();
        }
        this.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                if (s.length() >= 4) {
                    if (null != inputCompleteListener) {
                        inputCompleteListener.complete(getEditableText().toString());
                    }
                }
            }
        });
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int height = getMeasuredHeight();
        int width = getMeasuredWidth();

        height = Math.max(height, squareSize);

        int customWidth = height * maxLength + squareSpacing * (maxLength - 1);

        width = Math.max(width, customWidth);

        widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.getMode(widthMeasureSpec));
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.getMode(heightMeasureSpec));

        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        textColor = getCurrentTextColor();
        setTextColor(Color.TRANSPARENT);
        super.onDraw(canvas);

        setTextColor(textColor);

        drawSquareBackground(canvas);

        drawSquareText(canvas);
    }


    public void setInputCompleteListener(InputCompleteListener inputCompleteListener) {
        this.inputCompleteListener = inputCompleteListener;
    }


    private void drawSquareBackground(Canvas canvas) {
        rect.left = 0;
        rect.top = 0;
        rect.bottom = squareSize;
        rect.right = squareSize;

        int count = canvas.getSaveCount();

        canvas.save();

        int currentLength = getEditableText().length();

        for (int i = 0; i < maxLength; i++) {
            drawable.setBounds(rect);
            if (i < currentLength) {
                drawable.setState(new int[]{android.R.attr.state_focused});
            } else {
                drawable.setState(new int[]{android.R.attr.state_enabled});
            }
            drawable.draw(canvas);
            float dx = rect.right + squareSpacing;
            canvas.save();
            canvas.translate(dx, 0);
        }
        canvas.restoreToCount(count);
        canvas.translate(0, 0);
    }

    private void drawSquareText(Canvas canvas) {
        int count = canvas.getSaveCount();
        canvas.translate(0, 0);
        int currentLength = getEditableText().length();
        for (int i = 0; i < currentLength; i++) {
            String currentNumber = String.valueOf(getEditableText().charAt(i));
            TextPaint paint = getPaint();
            paint.setColor(textColor);
            paint.getTextBounds(currentNumber, 0, 1, rect);
            int x = squareSize / 2 + (squareSize + squareSpacing) * (i) - rect.centerX();
            int y = canvas.getHeight() / 2 + rect.height() / 2;
            canvas.drawText(currentNumber, x, y, paint);
        }
        canvas.restoreToCount(count);
    }

    public interface InputCompleteListener {
        void complete(String code);
    }
}
